package pong.lan;

import java.net.InetAddress;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import pong.Main;
import pong.rmi.ComRemota;
import pong.rmi.ComRemotaImpl;

public class Lan {
	public static ComRemota localhost;
	public static Object lock = new Object();
	public static HashMap<String, ComRemota> compus;
	public static LanUpdater updater;
	
	static{
		try {
			localhost = new ComRemotaImpl();
			compus = new HashMap<>();
		} catch (RemoteException e) {
			e.printStackTrace();
		}
	}
	
	public static void iniciar() {
		try {
			try{
				Registry registry = LocateRegistry.createRegistry(456);
				registry.rebind("pong", localhost);
			}catch (Exception e) {
				e.printStackTrace();
			}
			updater = new LanUpdater();
			updater.start();
			
			InetAddress local = InetAddress.getLocalHost();
			String hostname = local.getHostAddress();
			String temp = hostname.substring(0, hostname.lastIndexOf(".")+1);
			for(int k = 0; k<255; k++){
				String name = temp+k;
				ping(name, hostname);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private static void ping(final String name, final String hostname){
		new Thread(){
			public void run(){
				try{
					Registry registry = LocateRegistry.getRegistry(name, 456);
					ComRemota com = (ComRemota)registry.lookup("pong");
					if(com != null){
						add(com, name);
						com.add(hostname, localhost);
					}
				}catch(Exception e){}
				
			}
		}.start();
	}
	public static void add(ComRemota com, String name) throws RemoteException{
		synchronized (lock) {
			compus.put(com.getUUID(), com);
			actualizarLista();
		}
	}
	public static void actualizarLista(){
		try{
			List<ListItem> labels = new ArrayList<>();
			for(String x : compus.keySet()){
				ComRemota com = compus.get(x);
				try{
					String res = com.getNombreEnLista();
					if(res == null) continue;
					labels.add(new ListItem(com, res));
				}catch (Exception e) {}
			}
			Main.list.setListData(labels.toArray( new ListItem[labels.size()]));
		}catch(Exception e){e.printStackTrace();}
	}
	
	public static void perform(Object lock, HashMap<String, ComRemota> compus, final Run run){
		synchronized (lock) {
			for(String x: compus.keySet()){
				final ComRemota com = compus.get(x);
				new Thread(){
					public void run(){
						try{
							run.run(com);
						}catch (Exception e) {
							e.printStackTrace();
						}
					}
				}.start();
			}
		}
	}
	
	public static void perform(Run run){
		perform(lock, compus, run);
	}
	
	public static void actualizarListaGeneral(){
		perform(new Run() {
			@Override
			public void run(ComRemota com) throws Exception {
				com.actualizarLista();
			}
		});
	}
}
